From cbc6eb8357e39a78d13ad1e5d09546ae91b40349 Mon Sep 17 00:00:00 2001 From: "kaf24@scramble.cl.cam.ac.uk" Date: Thu, 25 Nov 2004 20:11:21 +0000 Subject: [PATCH] bitkeeper revision 1.1159.187.17 (41a63c69lFw9w4Qh2aZDluR-6MdrkQ) More hypercall preemption fixes. do_mmu_update() now correctly remembers the foreigndom across preempt/resume. --- xen/arch/x86/domain.c | 5 ++++- xen/arch/x86/memory.c | 44 +++++++++++++++++++++++++++++++--------- xen/arch/x86/traps.c | 5 +---- xen/common/dom_mem_ops.c | 8 +++----- xen/common/multicall.c | 3 +-- xen/include/xen/sched.h | 3 ++- 6 files changed, 45 insertions(+), 23 deletions(-) diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c index f5627a1ebd..47187ac118 100644 --- a/xen/arch/x86/domain.c +++ b/xen/arch/x86/domain.c @@ -427,7 +427,8 @@ long do_iopl(domid_t domain, unsigned int new_io_pl) return 0; } -void hypercall_create_continuation(unsigned int op, unsigned int nr_args, ...) +unsigned long hypercall_create_continuation( + unsigned int op, unsigned int nr_args, ...) { struct mc_state *mcs = &mc_state[smp_processor_id()]; execution_context_t *ec; @@ -455,6 +456,8 @@ void hypercall_create_continuation(unsigned int op, unsigned int nr_args, ...) } va_end(args); + + return op; } #endif diff --git a/xen/arch/x86/memory.c b/xen/arch/x86/memory.c index 4e83af76c2..5734f45ba9 100644 --- a/xen/arch/x86/memory.c +++ b/xen/arch/x86/memory.c @@ -126,10 +126,9 @@ static int mod_l1_entry(l1_pgentry_t *, l1_pgentry_t); static struct { #define DOP_FLUSH_TLB (1<<0) /* Flush the TLB. */ #define DOP_RELOAD_LDT (1<<1) /* Reload the LDT shadow mapping. */ - unsigned long deferred_ops; - unsigned long cr0; + unsigned long deferred_ops; /* If non-NULL, specifies a foreign subject domain for some operations. */ - struct domain *foreign; + struct domain *foreign; } __cacheline_aligned percpu_info[NR_CPUS]; /* @@ -1283,18 +1282,22 @@ int do_mmu_update( /* * We steal the m.s.b. of the @count parameter to indicate whether this * invocation of do_mmu_update() is resuming a previously preempted call. + * We steal the next 15 bits to remember the current FOREIGNDOM. */ -#define MMU_UPDATE_PREEMPTED (~(~0U>>1)) +#define MMU_UPDATE_PREEMPTED (~(~0U>>1)) +#define MMU_UPDATE_PREEMPT_FDOM_SHIFT ((sizeof(int)*8)-16) +#define MMU_UPDATE_PREEMPT_FDOM_MASK (0x7FFFU<> MMU_UPDATE_PREEMPT_FDOM_SHIFT; + count &= ~MMU_UPDATE_PREEMPT_FDOM_MASK; if ( unlikely(pdone != NULL) ) (void)get_user(done, pdone); + if ( (domid != current->id) && + !do_extended_command(0, MMUEXT_SET_FOREIGNDOM | (domid << 16)) ) + { + rc = -EINVAL; + goto out; + } } if ( unlikely(!array_access_ok(VERIFY_READ, ureqs, count, sizeof(req))) ) - return -EFAULT; + { + rc = -EFAULT; + goto out; + } for ( i = 0; i < count; i++ ) { if ( hypercall_preempt_check() ) { - hypercall_create_continuation( + rc = hypercall_create_continuation( __HYPERVISOR_mmu_update, 3, ureqs, - (count - i) | MMU_UPDATE_PREEMPTED, pdone); - rc = __HYPERVISOR_mmu_update; + (count - i) | + (FOREIGNDOM->id << MMU_UPDATE_PREEMPT_FDOM_SHIFT) | + MMU_UPDATE_PREEMPTED, pdone); break; } @@ -1459,6 +1482,7 @@ int do_mmu_update( ureqs++; } + out: if ( prev_pfn != 0 ) unmap_domain_mem((void *)va); diff --git a/xen/arch/x86/traps.c b/xen/arch/x86/traps.c index 5662a6388e..f07740220b 100644 --- a/xen/arch/x86/traps.c +++ b/xen/arch/x86/traps.c @@ -805,11 +805,8 @@ long do_set_trap_table(trap_info_t *traps) for ( ; ; ) { if ( hypercall_preempt_check() ) - { - hypercall_create_continuation( + return hypercall_create_continuation( __HYPERVISOR_set_trap_table, 1, traps); - return __HYPERVISOR_set_trap_table; - } if ( copy_from_user(&cur, traps, sizeof(cur)) ) return -EFAULT; diff --git a/xen/common/dom_mem_ops.c b/xen/common/dom_mem_ops.c index 373aee66c0..d675603cdf 100644 --- a/xen/common/dom_mem_ops.c +++ b/xen/common/dom_mem_ops.c @@ -23,14 +23,12 @@ #define START_EXTENT_SHIFT 4 /* op[:4] == start_extent */ #define PREEMPT_CHECK(_op) \ - if ( hypercall_preempt_check() ) { \ - hypercall_create_continuation( \ + if ( hypercall_preempt_check() ) \ + return hypercall_create_continuation( \ __HYPERVISOR_dom_mem_op, 5, \ (_op) | (i << START_EXTENT_SHIFT), \ extent_list, nr_extents, extent_order, \ - (d == current) ? DOMID_SELF : d->id); \ - return __HYPERVISOR_dom_mem_op; \ - } + (d == current) ? DOMID_SELF : d->id) static long alloc_dom_mem(struct domain *d, diff --git a/xen/common/multicall.c b/xen/common/multicall.c index 04b5a7bdd2..dfe5e8d691 100644 --- a/xen/common/multicall.c +++ b/xen/common/multicall.c @@ -60,9 +60,8 @@ long do_multicall(multicall_entry_t *call_list, unsigned int nr_calls) if ( i < nr_calls ) { mcs->flags = 0; - hypercall_create_continuation( + return hypercall_create_continuation( __HYPERVISOR_multicall, 2, &call_list[i], nr_calls-i); - return __HYPERVISOR_multicall; } } } diff --git a/xen/include/xen/sched.h b/xen/include/xen/sched.h index b0c8d70397..c8781f0440 100644 --- a/xen/include/xen/sched.h +++ b/xen/include/xen/sched.h @@ -218,7 +218,8 @@ void continue_cpu_idle_loop(void); void continue_nonidle_task(void); -void hypercall_create_continuation(unsigned int op, unsigned int nr_args, ...); +unsigned long hypercall_create_continuation( + unsigned int op, unsigned int nr_args, ...); #define hypercall_preempt_check() \ (unlikely(softirq_pending(smp_processor_id()))) -- 2.30.2